<script setup lang="ts">
import {
  ref,
  onMounted,
  watch,
  defineProps,
  nextTick,
  onUnmounted,
  defineExpose
} from "vue";
import {
  CylinderModelConfig,
  LocateSetData
} from "@/utils/appCommon/appCommonOptions/aeLocateConfigModel";
import * as PIXI from "pixi.js";
import { ellipseCircumference } from "@/views/apply/locateAnalysis/component/utils/commonThree";

// 定义接收的props
const props = defineProps<{
  locateSetting: LocateSetData;
  renderParams: {
    width: number;
    height: number;
    viewMode: number;
  };
  searchParams: any;
}>();

// PIXI相关引用
let app: PIXI.Application | null = null;
let container: PIXI.Container | null = null;
const gridSize = 10; // 10x10网格
const padding = 50; // 内边距50px

// 存储图形元素，直接使用DisplayObject类型
const objects = ref<Array<{
  x: number;
  y: number;
  type: 'sensor' | 'point';
  graphic: PIXI.DisplayObject;
  label?: PIXI.Text;
  tooltip?: PIXI.Container;
  id?: number
}>>([]);

// 传感器编号计数器
let sensorCounter = 1;

// 计算画布信息和网格单元大小
const calculateCanvasInfo = () => {
  // 与sphereFace2d.vue保持一致，直接使用可用宽度和高度除以网格大小
  const availableWidthPixels = props.renderParams.width - 2 * padding;
  const availableHeightPixels = props.renderParams.height - 2 * padding;
  const cellWidthPixels = availableWidthPixels / gridSize;
  const cellHeightPixels = availableHeightPixels / gridSize;

  // 获取柱面配置
  //@ts-ignore
  const modelConfig:CylinderModelConfig = props.locateSetting?.config?.modelConfig;
  console.log(modelConfig)
  const physicalDiameter = modelConfig?.cylinderDiameter || 100;
  const physicalCylinderLength = modelConfig?.cylinderLength || 100;
  const sealHeadType = modelConfig?.headType || 'none'; // none:无封头, top:上封头, bottom:下封头, both:两端封头
  const physicalSealHeadHeight = modelConfig?.headHeight || 0;

  // 计算柱体周长作为网格宽度的实际尺寸（物理尺寸）
  const physicalCylinderCircumference = Math.PI * physicalDiameter;

  // 计算高度实际尺寸（物理尺寸）
  let physicalTotalHeight = physicalCylinderLength;
  // 计算四分之一椭圆周长（物理尺寸）
  const physicalQuarterEllipseCircumference = ellipseCircumference(physicalDiameter / 2, physicalSealHeadHeight) / 4;

  if (sealHeadType === "top" || sealHeadType === "bottom") {
    // 上封头或下封头
    physicalTotalHeight += physicalQuarterEllipseCircumference;
  } else if (sealHeadType === "both") {
    // 两端封头
    physicalTotalHeight += 2 * physicalQuarterEllipseCircumference;
  }

  // 计算区域划分比例
  let bottomEllipseRatio = 0;
  let middleCylinderRatio = 1;
  let topEllipseRatio = 0;

  if (sealHeadType === 'none') {
    // 无封头
    middleCylinderRatio = 1;
  } else if (sealHeadType === "top") {
    // 上封头
    middleCylinderRatio = physicalCylinderLength / physicalTotalHeight;
    topEllipseRatio = physicalQuarterEllipseCircumference / physicalTotalHeight;
  } else if (sealHeadType === "bottom") {
    // 下封头
    bottomEllipseRatio = physicalQuarterEllipseCircumference / physicalTotalHeight;
    middleCylinderRatio = physicalCylinderLength / physicalTotalHeight;
  } else if (sealHeadType === "both") {
    // 两端封头
    bottomEllipseRatio = physicalQuarterEllipseCircumference / physicalTotalHeight;
    middleCylinderRatio = physicalCylinderLength / physicalTotalHeight;
    topEllipseRatio = physicalQuarterEllipseCircumference / physicalTotalHeight;
  }

  // 计算区域高度（基于可用高度，像素尺寸）
  const bottomEllipseHeightPixels = bottomEllipseRatio * availableHeightPixels;
  const middleCylinderHeightPixels = middleCylinderRatio * availableHeightPixels;
  const topEllipseHeightPixels = topEllipseRatio * availableHeightPixels;

  const res = {
    cellWidthPixels,
    cellHeightPixels,
    availableWidthPixels,
    availableHeightPixels,
    physicalCylinderCircumference,
    physicalTotalHeight,
    bottomEllipseHeightPixels,
    middleCylinderHeightPixels,
    topEllipseHeightPixels
  };
  console.log(res);
  return res;
};

// 初始化PIXI应用
const initPIXI = () => {
  console.log("初始化柱面2D视图");
  if (app) {
    app.destroy(true);
  }

  // 获取目标DOM元素
  const targetElement = document.querySelector('.cylinder-face-2d');
  if (!targetElement) {
    console.error("目标元素未找到");
    return;
  }

  // 清空目标元素
  targetElement.innerHTML = '';

  // 创建PIXI应用
  app = new PIXI.Application({
    width: props.renderParams.width,
    height: props.renderParams.height,
    backgroundColor: 0xffffff,
    antialias: true
  });

  // 手动将canvas添加到目标元素
  targetElement.appendChild(app.view);

  // 创建主容器
  container = new PIXI.Container();
  // 不设置容器位置，在drawGrid中直接使用padding作为起始坐标，与sphereFace2d.vue保持一致
  app.stage.addChild(container);

  // 重置传感器编号计数器
  sensorCounter = 1;

  // 绘制网格和区域
  drawGridAndAreas();

  // 添加初始示例传感器
  addInitialSensors();
};

// 绘制网格、区域和刻度
const drawGridAndAreas = () => {
  if (!app || !container) return;

  // 清空容器
  container.removeChildren();

  const {
    cellWidthPixels,
    cellHeightPixels,
    availableWidthPixels,
    availableHeightPixels,
    bottomEllipseHeightPixels,
    middleCylinderHeightPixels,
    topEllipseHeightPixels,
    physicalCylinderCircumference,
    physicalTotalHeight
  } = calculateCanvasInfo();

  // 使用padding作为起始坐标，与sphereFace2d.vue保持一致
  const startX = padding;
  const startY = padding;

  // 绘制不同区域的背景色，使用明显不同的颜色以区分区域
  const areaGraphics = new PIXI.Graphics();

  // 中间柱体区域 - 使用明显不同的颜色
  areaGraphics.beginFill("#ADD8E6", 0.5); // 绿色调，更明显
  areaGraphics.drawRect(startX, startY + bottomEllipseHeightPixels, availableWidthPixels, middleCylinderHeightPixels);
  areaGraphics.endFill();

  // 下椭圆区域（如果有）- 使用明显不同的颜色
  if (bottomEllipseHeightPixels > 0) {
    areaGraphics.beginFill(0xfff2e6, 0.5); // 浅蓝色，更明显
    areaGraphics.drawRect(startX, startY, availableWidthPixels, bottomEllipseHeightPixels);
    areaGraphics.endFill();
  }

  // 上椭圆区域（如果有）- 使用明显不同的颜色
  if (topEllipseHeightPixels > 0) {
    areaGraphics.beginFill(0xfff2e6, 0.5); // 浅橙色，更明显
    areaGraphics.drawRect(startX, startY + bottomEllipseHeightPixels + middleCylinderHeightPixels, availableWidthPixels, topEllipseHeightPixels);
    areaGraphics.endFill();
  }

  container.addChild(areaGraphics);

  // 绘制网格线
  const gridGraphics = new PIXI.Graphics();
  gridGraphics.lineStyle(1, 0xbbbbbb);

  // 垂直线
  for (let i = 0; i <= gridSize; i++) {
    const x = startX + i * cellWidthPixels;
    gridGraphics.moveTo(x, startY);
    gridGraphics.lineTo(x, startY + availableHeightPixels);

    // 偶数位显示X轴刻度（底侧）
    if (i % 2 === 0) {
      // 计算物理X坐标值（从左到右递增）
      const physicalX = (i / gridSize) * physicalCylinderCircumference;
      const displayValue = Math.round(physicalX * 10) / 10; // 保留一位小数
      const text = new PIXI.Text(displayValue.toString(), {
        fontSize: 10,
        fill: 0x333333
      });
      text.x = x - text.width / 2;
      text.y = startY + availableHeightPixels + 5;
      container.addChild(text);
    }
  }

  // 水平线
  for (let i = 0; i <= gridSize; i++) {
    const y = startY + i * cellHeightPixels;
    gridGraphics.moveTo(startX, y);
    gridGraphics.lineTo(startX + availableWidthPixels, y);

    // 偶数位显示Y轴刻度（左侧）
    if (i % 2 === 0) {
      // 计算物理Y坐标值（从下到上递增）- 使用1-i/gridSize确保底部为0
      const physicalY = (1 - i / gridSize) * physicalTotalHeight;
      const displayValue = Math.round(physicalY * 10) / 10; // 保留一位小数
      const text = new PIXI.Text(displayValue.toString(), {
        fontSize: 10,
        fill: 0x333333
      });
      text.x = startX - text.width - 5;
      text.y = y - text.height / 2;
      container.addChild(text);
    }
  }

  container.addChild(gridGraphics);

  // 绘制边界框
  const borderGraphics = new PIXI.Graphics();
  borderGraphics.lineStyle(2, 0x000000);
  borderGraphics.drawRect(startX, startY, availableWidthPixels, availableHeightPixels);
  container.addChild(borderGraphics);

  // 添加坐标轴标签
  const xLabel = new PIXI.Text('柱体周长 (mm)', {
    fontSize: 12,
    fill: 0x333333,
    fontWeight: 'bold'
  });
  xLabel.x = startX + availableWidthPixels / 2 - xLabel.width / 2;
  xLabel.y = startY + availableHeightPixels + 25;
  container.addChild(xLabel);

  const yLabel = new PIXI.Text('柱体高度 (mm)', {
    fontSize: 12,
    fill: 0x333333,
    fontWeight: 'bold'
  });
  yLabel.rotation = -Math.PI / 2;
  yLabel.x = startX - 40;
  yLabel.y = startY + availableHeightPixels / 2 + yLabel.width / 2;
  container.addChild(yLabel);

  // 重新添加已有的物体和点
  redrawObjects();

  // 确保应用渲染
  if (app) {
    app.renderer.render(app.stage);
  }
};

// 重新绘制所有传感器和点
const redrawObjects = () => {
  if (!container) return;

  // 创建新的物体数组，避免重复添加
  const objectsToRedraw = [...objects.value];
  objects.value = [];

  // 重置计数器，保留原有编号
  sensorCounter = 1;

  // 先找出最大编号，确保后续添加的传感器编号连续
  const maxSensorId = objectsToRedraw
    .filter(obj => obj.type === 'sensor' && obj.id)
    .reduce((max, obj) => Math.max(max, obj.id || 0), 0);

  if (maxSensorId > 0) {
    sensorCounter = maxSensorId + 1;
  }

  // 重新添加所有物体
  objectsToRedraw.forEach(obj => {
    if (obj.type === 'sensor') {
      addSensor(obj.x, obj.y, obj.id);
    } else {
      addPoint(obj.x, obj.y);
    }
  });
};

// 坐标转换：物理坐标到画布像素坐标
const physicalToCanvas = (physicalX: number, physicalY: number) => {
  const { physicalCylinderCircumference, physicalTotalHeight } = calculateCanvasInfo();

  // 使用padding作为起始坐标，与sphereFace2d.vue保持一致
  const startX = padding;
  const startY = padding;

  // 计算可用像素尺寸
  const availableWidthPixels = props.renderParams.width - 2 * padding;
  const availableHeightPixels = props.renderParams.height - 2 * padding;

  // 直接使用比例映射，不使用缩放因子
  // X坐标：使用物理X值占总周长的比例
  const canvasX = startX + (physicalX / physicalCylinderCircumference) * availableWidthPixels;
  // Y坐标：物理值越大，画布Y坐标越小（因为原点在画布左上角）
  const canvasY = startY + (1 - physicalY / physicalTotalHeight) * availableHeightPixels;

  return { x: canvasX, y: canvasY };
};

// 添加传感器/点到画布
const addObjectToCanvas = (physicalX: number, physicalY: number, type: 'sensor' | 'point', id?: number) => {
  if (!container || !app) return null;

  const { x: canvasX, y: canvasY } = physicalToCanvas(physicalX, physicalY);
  const graphic = new PIXI.Graphics();
  let label: PIXI.Text | undefined;
  let tooltip: PIXI.Container | undefined;

  if (type === 'sensor') {
    // 蓝色小方块
    graphic.beginFill(0x1E90FF);
    graphic.drawRect(-5, -5, 10, 10);
    graphic.endFill();

    // 为传感器添加编号标签
    label = new PIXI.Text(id?.toString() || '', {
      fontSize: 12,
      fill: 0x000000,
      fontWeight: 'bold'
    });
    label.x = canvasX + 8; // 标签显示在物体右侧
    label.y = canvasY - 6; // 垂直居中对齐
    container.addChild(label);

    // 创建tooltip容器
    tooltip = new PIXI.Container();
    tooltip.visible = false;

    // 添加tooltip背景
    const tooltipBg = new PIXI.Graphics();
    tooltipBg.beginFill(0x000000, 0.8);
    tooltipBg.drawRoundedRect(0, 0, 120, 40, 5);
    tooltipBg.endFill();
    tooltip.addChild(tooltipBg);

    // 添加tooltip文本
    const tooltipText = new PIXI.Text(`传感器 ${id}\nX: ${physicalX.toFixed(2)}mm\nY: ${physicalY.toFixed(2)}mm`, {
      fontSize: 9,
      fill: 0xffffff
    });
    tooltipText.x = 10;
    tooltipText.y = 5;
    tooltip.addChild(tooltipText);

    tooltip.x = canvasX + 15;
    tooltip.y = canvasY - 30;
    container.addChild(tooltip);

    // 设置交互属性
    graphic.interactive = true;
    graphic.buttonMode = true;

    // 添加鼠标悬浮事件
    graphic.on('mouseover', () => {
      if (tooltip) {
        tooltip.visible = true;
        app?.renderer.render(app.stage);
      }
    });

    graphic.on('mouseout', () => {
      if (tooltip) {
        tooltip.visible = false;
        app?.renderer.render(app.stage);
      }
    });
  } else {
    // 红色小圆点
    graphic.beginFill(0xFF3333);
    graphic.drawCircle(0, 0, 3);
    graphic.endFill();
  }

  graphic.x = canvasX;
  graphic.y = canvasY;
  container.addChild(graphic);

  // 确保应用渲染
  app.renderer.render(app.stage);

  return { graphic, label, tooltip };
};

// 添加传感器（蓝色方块）
const addSensor = (physicalX: number, physicalY: number, existingId?: number) => {
  const existingIndex = objects.value.findIndex(
    obj => obj.x === physicalX && obj.y === physicalY && obj.type === 'sensor'
  );

  if (existingIndex === -1) {
    const currentId = existingId || sensorCounter++;
    const result = addObjectToCanvas(physicalX, physicalY, 'sensor', currentId);
    if (result && result.graphic) {
      objects.value.push({
        x: physicalX,
        y: physicalY,
        type: 'sensor',
        graphic: result.graphic,
        label: result.label,
        tooltip: result.tooltip,
        id: currentId
      });
    }
    return currentId;
  }
  return -1;
};

// 添加点（红色圆点）
const addPoint = (physicalX: number, physicalY: number) => {
  const existingIndex = objects.value.findIndex(
    obj => obj.x === physicalX && obj.y === physicalY && obj.type === 'point'
  );

  if (existingIndex === -1) {
    const graphic = addObjectToCanvas(physicalX, physicalY, 'point');
    if (graphic) {
      objects.value.push({ x: physicalX, y: physicalY, type: 'point', graphic });
      return true;
    }
  }
  return false;
};

// 移除传感器或点
const removeObject = (physicalX: number, physicalY: number, type?: 'sensor' | 'point') => {
  const indicesToRemove: number[] = [];

  objects.value.forEach((obj, index) => {
    if (obj.x === physicalX && obj.y === physicalY && (!type || obj.type === type)) {
      // 移除鼠标事件监听
      if (obj.graphic) {
        obj.graphic.removeAllListeners();
        if (container) {
          container.removeChild(obj.graphic);
        }
      }
      // 移除标签
      if (obj.label && container) {
        container.removeChild(obj.label);
      }
      // 移除tooltip
      if (obj.tooltip && container) {
        container.removeChild(obj.tooltip);
      }
      indicesToRemove.push(index);
    }
  });

  // 从后往前移除，避免索引变化问题
  indicesToRemove.sort((a, b) => b - a).forEach(index => {
    objects.value.splice(index, 1);
  });

  // 重新渲染
  if (app) {
    app.renderer.render(app.stage);
  }

  return indicesToRemove.length > 0;
};

// 添加初始示例传感器
const addInitialSensors = () => {
  // 获取柱面配置
  //@ts-ignore
  const modelConfig:CylinderModelConfig = props.locateSetting?.config?.modelConfig;
  const physicalDiameter = modelConfig?.cylinderDiameter || 100;
  const physicalCylinderLength = modelConfig?.cylinderLength || 100;
  const sealHeadType = modelConfig?.headType || "none";
  const physicalSealHeadHeight = modelConfig?.headHeight || 0;

  // 计算柱体周长（物理尺寸）
  const physicalCylinderCircumference = Math.PI * physicalDiameter;

  // 计算四分之一椭圆周长（物理尺寸）
  const physicalQuarterEllipseCircumference = ellipseCircumference(physicalDiameter / 2, physicalSealHeadHeight) / 4;

  // 根据不同的封头类型，计算合适的初始点位置（物理尺寸）
  let physicalStartY = 0;
  if (sealHeadType === "bottom" || sealHeadType === "both") {
    physicalStartY = physicalQuarterEllipseCircumference * 0.5; // 从下封头中部开始
  }

  // 添加一些示例传感器（在柱体上均匀分布）
  addSensor(physicalCylinderCircumference * 0.1, physicalStartY + physicalCylinderLength * 0.2);
  addSensor(physicalCylinderCircumference * 0.3, physicalStartY + physicalCylinderLength * 0.5);
  addSensor(physicalCylinderCircumference * 0.6, physicalStartY + physicalCylinderLength * 0.7);
  addSensor(physicalCylinderCircumference * 0.8, physicalStartY + physicalCylinderLength * 0.3);

  // 添加一些示例点
  addPoint(physicalCylinderCircumference * 0.2, physicalStartY + physicalCylinderLength * 0.4);
  addPoint(physicalCylinderCircumference * 0.5, physicalStartY + physicalCylinderLength * 0.6);
  addPoint(physicalCylinderCircumference * 0.7, physicalStartY + physicalCylinderLength * 0.2);
};

// 暴露方法给父组件
defineExpose({
  addSensor,
  addPoint,
  removeObject
});

// 监听参数变化
watch(() => props.locateSetting, (newVal) => {
  console.log('CylinderFace2D - 定位配置变化:', newVal);
  // 当配置变化时，重新初始化PIXI
  nextTick(() => {
    initPIXI();
  });
}, { deep: true, immediate: true });

// 监听渲染参数变化，重新初始化PIXI
watch(() => props.renderParams, (newVal) => {
  console.log('CylinderFace2D - 渲染参数变化:', newVal);
  nextTick(() => {
    initPIXI();
  });
}, { deep: true, immediate: true });

watch(() => props.searchParams, (newVal) => {
  console.log('CylinderFace2D - 搜索参数变化:', newVal);
  // 2D视图对searchParams变化的处理逻辑
}, { deep: true, immediate: true });

// 清理资源和事件监听器
const cleanup = () => {
  if (app) {
    // 移除所有物体的事件监听
    objects.value.forEach(obj => {
      if (obj.graphic) {
        // 安全地移除事件监听器，避免方法不存在的错误
        if (typeof obj.graphic.removeAllListeners === 'function') {
          obj.graphic.removeAllListeners();
        }
      }
    });

    // 销毁应用
    app.destroy(true);
    app = null;
    container = null;
    objects.value = [];
  }
};

onMounted(() => {
  console.log('CylinderFace2D组件已挂载');
  nextTick(() => {
    initPIXI();
  });
});

onUnmounted(() => {
  console.log('CylinderFace2D组件已卸载');
  cleanup();
});
</script>

<template>
  <div class="cylinder-face-2d" :style="{ width: renderParams.width + 'px', height: renderParams.height + 'px' }"></div>
</template>

<style scoped lang="scss">
.cylinder-face-2d {
  width: 100%;
  height: 100%;
  background-color: #ffffff;
  border: 1px solid #e0e0e0;
  border-radius: 4px;
  overflow: hidden;
  position: relative;
}

.cylinder-face-2d canvas {
  display: block;
}
</style>
